package com.ziq.zcamp.util.list;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Looper;

import androidx.databinding.ObservableList;
import androidx.recyclerview.widget.RecyclerView;

import java.lang.ref.SoftReference;

public class ObservableListUtil {

    public static <DATA> void observableListBind(final ObservableList<DATA> dataList,final RecyclerView.Adapter<?> adapter){
        dataList.addOnListChangedCallback(getListChangedCallback(adapter));
    }

    private static class ChangedCallback<DATA> extends ObservableList.OnListChangedCallback<ObservableList<DATA>>{
        private final Handler mHandler = new Handler(Looper.getMainLooper());
        private final SoftReference<RecyclerView.Adapter<?>> reference;

        public ChangedCallback(RecyclerView.Adapter<?> adapter) {
            reference = new SoftReference<>(adapter);
        }

        private RecyclerView.Adapter<?> adapter(){
            return reference.get();
        }

        @SuppressLint("NotifyDataSetChanged")
        @Override
        public void onChanged(ObservableList observableList) {
            if (Looper.getMainLooper() == Looper.myLooper()){
                if (adapter()!=null){
                    adapter().notifyDataSetChanged();
                }
            }else {
                mHandler.post(() -> {
                    if (adapter()!=null){
                        adapter().notifyDataSetChanged();
                    }
                });
            }
        }

        @Override
        public void onItemRangeChanged(ObservableList observableList, int i, int i1) {
            if (Looper.getMainLooper() == Looper.myLooper()){
                if (adapter()!=null){
                    adapter().notifyItemRangeChanged(i, i1);
                }
            }else {
                mHandler.post(() -> {
                    if (adapter()!=null){
                        adapter().notifyItemRangeChanged(i, i1);
                    }
                });
            }
        }

        @Override
        public void onItemRangeInserted(ObservableList observableList, int i, int i1) {
            if (Looper.getMainLooper() == Looper.myLooper()){
                if (adapter()!=null){
                    adapter().notifyItemRangeInserted(i, i1);
                }
            }else {
                mHandler.post(() -> {
                    if (adapter()!=null){
                        adapter().notifyItemRangeInserted(i, i1);
                    }
                });
            }
        }

        @SuppressLint("NotifyDataSetChanged")
        @Override
        public void onItemRangeMoved(ObservableList observableList, int i, int i1, int i2) {
            if (Looper.getMainLooper() == Looper.myLooper()){
                if (i2 == 1) {
                    if (adapter()!=null){
                        adapter().notifyItemMoved(i, i1);
                    }
                } else {
                    if (adapter()!=null){
                        adapter().notifyDataSetChanged();
                    }
                }
            }else {
                mHandler.post(() -> {
                    if (i2 == 1) {
                        if (adapter()!=null){
                            adapter().notifyItemMoved(i, i1);
                        }
                    } else {
                        if (adapter()!=null){
                            adapter().notifyDataSetChanged();
                        }
                    }
                });
            }
        }

        @Override
        public void onItemRangeRemoved(ObservableList observableList, int i, int i1) {
            if (Looper.getMainLooper() == Looper.myLooper()){
                if (adapter()!=null){
                    adapter().notifyItemRangeRemoved(i, i1);
                }
            }else {
                mHandler.post(() -> {
                    if (adapter()!=null){
                        adapter().notifyItemRangeRemoved(i, i1);
                    }
                });
            }
        }
    }

    public static <DATA> ObservableList.OnListChangedCallback<ObservableList<DATA>> getListChangedCallback(final RecyclerView.Adapter<?> adapter) {
        return new ChangedCallback<>(adapter);
    }
}
